package com.leve.admin.service.impl;

import com.google.gson.Gson;
import com.leve.admin.common.CheckSumBuilder;
import com.leve.admin.common.HTTPSimple;
import com.leve.admin.common.JedisUtil;
import com.leve.admin.domain.*;
import com.leve.admin.repository.GhostRepository;
import com.leve.admin.service.ReceiverService;
import com.mongodb.DBRef;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.json.simple.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import redis.clients.jedis.Jedis;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Future;

//import org.json.simple.JSONArray;

@Service
@Slf4j
public class ReceiverServiceImpl implements ReceiverService {
    @Autowired
    private GhostRepository mongo;
    @Value("${yunxin.appKey}")
    private String appKey;
    @Value("${yunxin.appSecret}")
    private String appSecret;
    @Value("${yunxin.gaode}")
    private String gaode;

    public Document isCustomer(String accid) {
        return mongo.findGhostByAccid(accid);
    }

    public Future<String> sendMessage(String from, String to, String msg) {
        addUser(from, to);
        String url = "https://api.netease.im/nimserver/msg/sendMsg.action";
        HttpHeaders headers = getHttpHeaders();
        Gson gson = new Gson();
        Map<String, String> bodyMap = new HashMap();
        bodyMap.put("msg", msg);
        MultiValueMap<String, String> body = new LinkedMultiValueMap();
        body.add("from", from);
        body.add("ope", "0");
        body.add("to", to);
        body.add("type", "0");
        body.add("body", gson.toJson(bodyMap));
        ResponseEntity<NetEaseRespVo> responseEntity = getMapResponseEntity(url, headers, body);
        log.info("yunxin service  sendMessage    {} ", ((NetEaseRespVo) responseEntity.getBody()).toString());
        NetEaseRespVo body2 = (NetEaseRespVo) responseEntity.getBody();
        DataVo data = body2.getData();
        FaccidVo faccid = body2.getFaccid();
        TeamInfo tinfo = body2.getTinfo();

        String dataStr = data != null ? data.toString() : "data is null";

        String faccidStr = faccid != null ? faccid.toString() : "faccid is null";

        String tinfoStr = tinfo != null ? tinfo.toString() : "tinfo is null";

        log.info("yunxin service  sendMessage    {} ", ((NetEaseRespVo) responseEntity.getBody()).getCode() + "DataStr:" + dataStr + "   faccidStr:" + faccidStr + "   tinfoStr:" + tinfoStr);
        return new AsyncResult(((NetEaseRespVo) responseEntity.getBody()).toString());
    }

    @Override
    public Future<String> sendBatchMsg(String from, JSONArray to, String msg) {
        String url = "https://api.netease.im/nimserver/msg/sendBatchMsg.action";
        HttpHeaders headers = getHttpHeaders();
        Gson gson = new Gson();
        Map<String, String> bodyMap = new HashMap();
        bodyMap.put("msg", msg);
        MultiValueMap<String, String> body = new LinkedMultiValueMap();
        body.add("fromAccid", from);
        //  body.add("ope", "0");
        body.add("toAccids", to.toJSONString());
        body.add("type", "0");
        body.add("body", gson.toJson(bodyMap));
        ResponseEntity<NetEaseRespVo> responseEntity = getMapResponseEntity(url, headers, body);
        log.info("yunxin service  sendMessage    {} ", ((NetEaseRespVo) responseEntity.getBody()).toString());
        NetEaseRespVo body2 = (NetEaseRespVo) responseEntity.getBody();
        DataVo data = body2.getData();
        FaccidVo faccid = body2.getFaccid();
        TeamInfo tinfo = body2.getTinfo();

        String dataStr = data != null ? data.toString() : "data is null";

        String faccidStr = faccid != null ? faccid.toString() : "faccid is null";

        String tinfoStr = tinfo != null ? tinfo.toString() : "tinfo is null";

        log.info("yunxin service  sendMessage    {} ", ((NetEaseRespVo) responseEntity.getBody()).getCode() + "DataStr:" + dataStr + "   faccidStr:" + faccidStr + "   tinfoStr:" + tinfoStr);
        return new AsyncResult(((NetEaseRespVo) responseEntity.getBody()).toString());
    }


    public Future<String> sendMessage(String from, String to, Object data, String type, String ext) {
        addUser(from, to);
        String url = "https://api.netease.im/nimserver/msg/sendMsg.action";
        HttpHeaders headers = getHttpHeaders();
        Gson gson = new Gson();
        MultiValueMap<String, String> body = new LinkedMultiValueMap();
        body.add("from", from);
        body.add("ope", "0");
        body.add("to", to);
        body.add("type", type);
        body.add("ext", ext);
        body.add("body", gson.toJson(data));
        ResponseEntity<NetEaseRespVo> responseEntity = getMapResponseEntity(url, headers, body);
        log.info("yunxin service  sendMessage    {} ", ((NetEaseRespVo) responseEntity.getBody()).toString());
        NetEaseRespVo body2 = (NetEaseRespVo) responseEntity.getBody();
        FaccidVo faccid = body2.getFaccid();
        TeamInfo tinfo = body2.getTinfo();

        String faccidStr = faccid != null ? faccid.toString() : "faccid is null";

        String tinfoStr = tinfo != null ? tinfo.toString() : "tinfo is null";

        log.info("yunxin service  sendMessage    {} ", ((NetEaseRespVo) responseEntity.getBody()).getCode() + "   faccidStr:" + faccidStr + "   tinfoStr:" + tinfoStr);
        return new AsyncResult(((NetEaseRespVo) responseEntity.getBody()).toString());
    }

    public Future<String> addUser(String accid, String faccid) {
        String url = "https://api.netease.im/nimserver/friend/add.action";
        HttpHeaders headers = getHttpHeaders();
        Gson gson = new Gson();
        MultiValueMap<String, String> body = new LinkedMultiValueMap();
        body.add("accid", accid);
        body.add("faccid", faccid);
        body.add("type", "1");
        ResponseEntity<NetEaseRespVo> responseEntity = getMapResponseEntity(url, headers, body);
        log.info("yunxin service  sendMessage    {} ", ((NetEaseRespVo) responseEntity.getBody()).toString());
        NetEaseRespVo body2 = (NetEaseRespVo) responseEntity.getBody();
        DataVo data = body2.getData();
        FaccidVo facc = body2.getFaccid();
        TeamInfo tinfo = body2.getTinfo();

        String dataStr = data != null ? data.toString() : "data is null";

        String faccidStr = facc != null ? facc.toString() : "facc is null";

        String tinfoStr = tinfo != null ? tinfo.toString() : "tinfo is null";

        log.info("yunxin service  addUser    {} ", ((NetEaseRespVo) responseEntity.getBody()).getCode() + "DataStr:" + dataStr + "   faccidStr:" + faccidStr + "   tinfoStr:" + tinfoStr);
        return new AsyncResult(((NetEaseRespVo) responseEntity.getBody()).toString());
    }

    private HttpHeaders getHttpHeaders() {
        String nonce = UUID.randomUUID().toString();
        String curTime = String.valueOf(new Date().getTime() / 1000L);
        String checkSum = CheckSumBuilder.getCheckSum(this.appSecret, nonce, curTime);
        return getHttpHeaders(nonce, curTime, checkSum);
    }

    private HttpHeaders getHttpHeaders(String nonce, String curTime, String checkSum) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("AppKey", this.appKey);
        headers.add("Nonce", nonce);
        headers.add("CurTime", curTime);
        headers.add("CheckSum", checkSum);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        return headers;
    }

    private <T extends MultiValueMap> ResponseEntity<NetEaseRespVo> getMapResponseEntity(String url, HttpHeaders headers, T body) {
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity(body, headers);

        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.postForEntity(url, entity, NetEaseRespVo.class, new Object[0]);
    }

    public String toSay(Ghost ghost)
            throws InterruptedException {

        log.info("===========================进入招呼系统  userId : " + ghost.getUser_id() + "===== ghostId ===" + ghost.getId() + "===================");
        String to = ghost.getIm_id();
        Gender gender = ghost.getGender();
        List<Ghost> list = new ArrayList();
        if (Gender.MALE.equals(gender)) {
            //TODO 查询性别 4
            list = mongo.selectBySex("FEMALE");
        } else {
            //TODO 查询性别 3
            list = mongo.selectBySex("MALE");
        }
        List<Ghost> randomList = getRandomList(list, 8);
        int count = 0;
        String owner = "";
        String friend = "";
        String from = "";
        Jedis jedis = JedisUtil.getJedis();
        jedis.append(ghost.getId(), "false");
        jedis.expire(ghost.getId(), 240);
        try {
            JedisUtil.returnResource(jedis);
        } catch (Exception e) {
            JedisUtil.returnBrokenResource(jedis);
        }
        String msg[] = {"哈哈，终于逮到活的了", "你是我附近的人？", "可以相互认识下吗?"};
        boolean weekend = isWeekend();
        do {
            if (count == 0) {
                Ghost ghost0 = randomList.get(0);
                String ghost_0_id = ghost0.getId();
                from = ghost0.getIm_id();
                String say = toSay(ghost_0_id, ghost.getId());
                log.info("===========================正在进行打招呼" + count + " 请求返回参数" + say + "===========================");
                owner = ghost.getId();
                friend = ghost_0_id;
                if (!weekend) {
                    final Future<String> sendMessage = ReceiverServiceImpl.this.sendMessage(randomList.get(7 - count).getIm_id(), to, msg[count]);
                }

                selectFriend(owner, friend, from, to);
                count++;
            }
            if (count < 5) {
                Thread.sleep(30000L);
                String flag = jedis.get(owner);
                if ((flag != null) && ("true".equals(flag))) {
                    break;
                }
                if (count <= 2) {
                    if (!weekend) {
                        final Future<String> sendMessage = ReceiverServiceImpl.this.sendMessage(randomList.get(7 - count).getIm_id(), to, msg[count]);
                    }

                }

                Ghost ghost0 = randomList.get(count);
                String ghost_0_Id = ghost0.getId();
                String say = toSay(ghost_0_Id, ghost.getId());
                log.info("===========================正在进行打招呼" + count + "请求返回参数" + say + "===========================");
                owner = ghost.getId();
                count++;
            }
        } while (count < 5);
        return "completes";
    }

    private String toSay(String from, String to) {
        String url = "https://api.leve.com/land/v1/ghosts/" + from + "/friends/" + to;
        GhostFriend friend = new GhostFriend();
        friend.setAction(GhostAction.GREET);
        friend.setFrom(GhostFrom.ENCOUNTER);
        Gson gson = new Gson();
        String json = gson.toJson(friend);
        return HTTPSimple.PUT(url, json);
    }

    public String findGhost() {
        Document queryDoc = new Document();
        queryDoc.put("user_id", "1");
        //   Document selectOne = this.mongo.selectOne("ghost", queryDoc);
        Document selectOne = null;
        Object object = selectOne.get("_id");
        System.out.println(object);
        return selectOne.toJson();
    }

    @Override
    public String testToSay() {
        return null;
    }

    public static List<Ghost> getRandomList(List<Ghost> paramList, int count) {
        if (paramList.size() < count) {
            return paramList;
        }
        Random random = new Random();
        List<Integer> tempList = new ArrayList();
        List<Ghost> newList = new ArrayList();
        int temp = 0;
        for (int i = 0; i < count; i++) {
            temp = random.nextInt(paramList.size());
            if (!tempList.contains(Integer.valueOf(temp))) {
                tempList.add(Integer.valueOf(temp));
                newList.add(paramList.get(temp));
            } else {
                i--;
            }
        }
        return newList;
    }

    public String toSayFlag(String owner) {
        DBRef sender = new DBRef("ghost", new ObjectId(owner));
        Document queryDoc3 = new Document();
        queryDoc3.append("sender", sender);
        // Document selectOne = this.mongo.selectOne("ghostGreeting", queryDoc3);
        return "";
    }

    public Future<String> ghostSendMsg(String from, String to) {
        String url = "https://api.netease.im/nimserver/msg/sendMsg.action";
        HttpHeaders headers = getHttpHeaders();
        Gson gson = new Gson();
        Map<String, String> bodyMap = new HashMap();
        bodyMap.put("msg", "����������������������");
        MultiValueMap<String, String> body = new LinkedMultiValueMap();
        body.add("from", from);
        body.add("ope", "0");
        body.add("to", to);
        body.add("type", "0");
        body.add("body", gson.toJson(bodyMap));
        ResponseEntity<NetEaseRespVo> responseEntity = getMapResponseEntity(url, headers, body);
        log.info("yunxin service  sendMessage    {} ", ((NetEaseRespVo) responseEntity.getBody()).toString());
        NetEaseRespVo body2 = (NetEaseRespVo) responseEntity.getBody();
        int code = body2.getCode();
        DataVo data = body2.getData();
        FaccidVo faccid = body2.getFaccid();
        TeamInfo tinfo = body2.getTinfo();
        System.out.println(data.toString());
        return new AsyncResult(((NetEaseRespVo) responseEntity.getBody()).toString());
    }

    public String joinTeams(String accid) {
        String url = "https://api.netease.im/nimserver/team/joinTeams.action";
        HttpHeaders headers = getHttpHeaders();
        Gson gson = new Gson();
        MultiValueMap<String, String> body = new LinkedMultiValueMap();
        body.add("accid", accid);
        ResponseEntity<NetEaseRespVo> responseEntity = getMapResponseEntity(url, headers, body);
        log.info("yunxin service  create  {} ", responseEntity.getBody());
        NetEaseRespVo body2 = (NetEaseRespVo) responseEntity.getBody();
        TeamInfo tinfo = body2.getTinfo();

        return tinfo.toString();
    }

    public String sendUp(String from, String to) {
        if (from != null) {
            String[] str = from.split("-");
            if (str.length > 1) {
                from = str[1];
            }
        }
        Document fromObj = mongo.findGhostByAccid(from);
        Document toObj = mongo.findGhostByAccid(from);
        String prodUrl = "https://api.leve.com/land/v1/ghosts/" + fromObj.getString("_id") + "/followings/" + toObj.getString("_id");
        String put = HTTPSimple.put(prodUrl);
        log.info(put);
        return put;
    }

    public Map<String, Object> findGhost(String userAccid, String adminAccid) {
        if (adminAccid != null) {
            String[] str = adminAccid.split("-");
            if (str.length > 1) {
                adminAccid = str[1];
            }
        }
        Document userObj = mongo.findGhostByAccid(userAccid);
        Document admin = mongo.findGhostByAccid(adminAccid);
        Double birthdayByuser = Double.valueOf(toBirthday(userObj.get("birthday").toString()));
        userObj.append("birthday", Integer.valueOf(birthdayByuser.intValue()));
        Object locationObj = userObj.get("location");
        List location = (List) locationObj;
        if ((location != null) && (location.size() > 0)) {
            Object longitude = location.get(0);
            Object latitude = location.get(1);
            String url = this.gaode + "&location=" + longitude + "," + latitude;
            String get = HTTPSimple.GET(url);
            log.info("===========================" + get + "===========================");
            Gson gson = new Gson();
            Map gaode = (Map) gson.fromJson(get, Map.class);
            Object status = gaode.get("status");
            if ("1".equals(status)) {
                Object object = gaode.get("regeocode");
                Map regeocode = (Map) object;
                Object formatted_address = regeocode.get("formatted_address");
                userObj.put("address", formatted_address);
            }
        }
        List<Document> postUsers = mongo.selectByUid(userObj.get("user_id").toString());
        if (postUsers.size() >= 5) {
            List<Document> subList = postUsers.subList(0, 5);
            userObj.append("moments", subList);
        } else {
            userObj.append("moments", postUsers);
        }
        List<Document> postAdmins = this.mongo.selectByUid(admin.get("user_id").toString());
        String string = admin.get("birthday").toString();

        Double birthdayByadmin = Double.valueOf(toBirthday(admin.get("birthday").toString()));
        admin.append("birthday", Integer.valueOf(birthdayByadmin.intValue()));
        if (postAdmins.size() >= 5) {
            List<Document> subList = postAdmins.subList(0, 5);
            admin.append("moments", subList);
        } else {
            admin.append("moments", postAdmins);
        }
        Map<String, Object> result = new HashMap();
        result.put("adminMsg", admin);
        result.put("userMsg", userObj);
        result.put("flag", Boolean.valueOf(true));
        return result;
    }


    private double toBirthday(String birthday) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy.MM");
        String currentData = df.format(new Date());
        double age = 0.0D;
        try {
            Date date = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH).parse(birthday);
            String odlData = new SimpleDateFormat("yyyy.MM").format(new Date(date.getTime()));
            age = new Double(currentData).doubleValue() - new Double(odlData).doubleValue();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return age;
    }

    public void selectFriend(final String owner, final String friend, final String from, final String to) {
        final Jedis jedis = JedisUtil.getJedis();
        final Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                final String[] msg = {"hello~  哎呀", "你好呀  哈哈哈", "我竟然打招呼成功了 你好你好 来了来了", "你好哦"};
                int count = 0;
                while (true) {
                    try {
                        Thread.sleep(600L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    final DBRef receiver = new DBRef("ghost", new ObjectId(owner));
                    final Document queryDoc3 = new Document();
                    queryDoc3.append("receiver", receiver);
                    queryDoc3.append("status", "ACCEPTED");
                    final Document selectOne = ReceiverServiceImpl.this.mongo.selectOneByGhostGreet(owner);
                    if (selectOne != null) {
                        final String flag = jedis.get(owner);
                        jedis.set(owner, "true");
                        final Future<String> sendMessage = ReceiverServiceImpl.this.sendMessage(from, to, msg[count]);
                        jedis.close();
                        log.info("===========================" + sendMessage + "消息已经发送===========================");
                        ++count;
                        break;
                    }
                    final String flag = jedis.get(owner);
                    if (flag == null) {
                        try {
                            JedisUtil.returnResource(jedis);
                        } catch (Exception e2) {
                            JedisUtil.returnBrokenResource(jedis);
                        }
                        break;
                    }
                    log.info("===========================" + owner + "是否接受招呼===========================");
                }
            }
        });
        t1.start();
    }

    public boolean isWeekend() {
        Calendar calendar = Calendar.getInstance();
        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (week == 0 || week == 6) {
            return true;
        }
        return false;
    }

}
